public class CreateJointCall{
/**********************************************************************
 Name:  CreateJointCall()
 Purpose:  search out CallPlan records and create joint call                                                          
======================================================
History                                                            
-------                                                            
VERSION  AUTHOR            DATE              DETAIL                                
   1.0 -      li siheng         09/03/2011         Create          : 
======================================================
Review History                                                            
-------  
VERSION    REVIEWER    DATE          DETAIL
  1.0         WP      05/06/2011    1. class的注释应该放到class体外，且class之上
                                    2. 缺少全局变量与属性的注释
                                    3. 变量和属性的布局、命名请遵循开发规范
                                    4. 大部分方法缺少注释，部分方法的注释不完整，如：SearchMsr，需要加上参数和返回值的说明
                                    5. 构造函数CreateJointCall最后一个if语句里判断“Medical Sales”条件没考虑充分
                                    6. 方法体中的代码注释不足
                                    7. submit方法
                                        7.1 for loop里有DML，需要优化，优化方法待研究
                                        7.2 DML语句未做异常处理
                                    8. search方法中的第二个if语句不应该存在，应该是第一个if语句的else部分
                                    9. SearchMsr方法里判断“Medical Sales”条件没考虑充分
                                    10. 属性CityList中的for循环可以进行优化，直接放入构造函数使用SOQL获取
                                    11. testMethod中模拟的用户角色不足
************************************************************************/
  
    public string CityValue{get;set;}
    public List<SelectOption> MSRList{get;set;}
    public list<place__c> PlaceL{get;set;}
    public user CurrentUser{get;set;}
    public list<User> AllUserList{get;set;}
    public List<user> AllMsr{get;set;}
    public string MSRL{get;set;}
    public string NullCallDateError{get;set;}//{get{NullCallDateError='请填写拜访日期';return NullCallDateError;}set;}
    public boolean showError{get;set;}
    public string msg{get;set;}
    public string MonthlyJointCallId{get;set;}
    public date PlanMonth{get;set;}
    public jointcall__c jointCall{
        get{
            if(jointCall== null){
                jointCall= new JointCall__c();             
            }
            return jointcall;
        }
        set;
    }
    
    public list<CallPlanEntry> CallPlan{
        get{
            if(callplan==null)
            callplan=new list<CallPlanEntry>();
            return callplan;
        }
        set;
    }
    
    public CreateJointCall(ApexPages.StandardController controller) {
        this.controller = controller;
        placeL=[select Id,Name,Region__r.Name,Subregion__r.Name,Area__r.Name,PlaceType__c  from Place__c];
        CurrentUser=[select Id,Name,UserRegion__c,UserSubRegion__c,UserAreaValue__c,UserCity__c from User where Id=:UserInfo.getUserId()];
        Profile prof=[select Name from Profile where Id=: UserInfo.getProfileId()];
        try{
            MonthlyJointCallId=System.currentPageReference().getParameters().get('retURL').substring(1,16);
        }catch(exception e){
           // MonthlyJointCallId=[select id from Monthly_Joint_Call__c where MonthFormula__c=:date.today().month() and YearFormula__c=:date.today().year() and ownerid=:userinfo.getuserid() ].id;
        }
        Monthly_Joint_Call__c MonthlyJointCall=new Monthly_joint_call__c();
        try{
            MonthlyJointCall=[select MonthFormula__c,YearFormula__c,id from Monthly_Joint_Call__c where id=:MonthlyJointCallId limit 1];
        }catch(QueryException qe){
            MonthlyJointCall=null;
        }catch(exception e){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL,e.getMessage()));
        }
        if(MonthlyJointCall!=null)
            planMonth=date.newInstance(integer.valueof(MonthlyJointCall.YearFormula__c),integer.valueof(MonthlyJointCall.MonthFormula__c),1);
        if(MSRList==null)
            MSRList=new List<SelectOption>();
        else
            MSRList.clear();

        MSRList.add(new SelectOption('0','所有MSR'));
        
        showError=false;       
        allmsr=new list<user>(); 
        //搜索出所有MSR
        AllUserList=[select id,managerID,FunctionDepartment__c,Title__c,name,UserRegion__c,UserSubRegion__c,UserAreaValue__c,UserCity__c
                              from User where FunctionDepartment__c !='Trade Sales' order by Name];//搜出所有用户，排除TSR
       
       if(prof.Name=='System Administrator' || prof.Name=='系统管理员')
        {
            for(User u:AllUserList)//添加所有MSR
            {
                if(u.Title__c == 'Sales Rep' && u.FunctionDepartment__c =='Medical Sales'){
                    AllMsr.add(u);
                    MSRList.add(new SelectOption(u.Id,u.Name));
                }
            }
        }else{
            set<id> US=new set<id>();
            Us.add((id)userinfo.getuserid());
            SearchMsr(us);
        }
        JointCall.SearchDate__c = date.newInstance(integer.valueof(MonthlyJointCall.YearFormula__c), integer.valueof(MonthlyJointCall.MonthFormula__c), 1);
    }
    
    private final ApexPages.StandardController controller;
    
    
    
    public PageReference submit(){
   
        /*
        if(JointCall.SearchDate__c==null){
            showError=true;
            return null;
        }
        */

        list<Monthly_Joint_Call__c> MJCL=[select id,year__c,month__c from Monthly_Joint_Call__c where yearFormula__c>=:date.today().year() and monthFormula__c >=: date.today().month() and ownerid = :userinfo.getuserid() order by Yearformula__c,MonthFormula__c];
        map<string,id> MJCMap=new map<string,id>();
        list<JointCall__c> UpsertJointCallList=new list<JointCall__c>();
        for(Monthly_Joint_Call__c m:mjcl){
            mjcmap.put(''+m.year__c+m.month__c,m.id);
        }
        id MJCID;//Monthly Joint Call ID
        list<MessageRecipient__c> insertMessageRecipientList=new list<MessageRecipient__c>();
        map<Id,Id> MSRIds = new map<Id,Id>();

        for(CallPlanEntry cp:CallPlan){
            if(cp.checked){

                if(mjcmap.containskey(''+cp.callplan.CallPlanDate__c.year()+cp.CallPlan.CallPlanDate__c.month())){
                    mjcid=mjcmap.get(''+cp.callplan.CallPlanDate__c.year()+cp.CallPlan.CallPlanDate__c.month());
                }else{
                    Monthly_Joint_Call__c newMJC=new Monthly_Joint_Call__c(
                        ownerid=userinfo.getuserid(),
                        name=userinfo.getname()+' '+string.valueof(cp.callplan.callplandate__c.year())+'年'+string.valueof(cp.callplan.callplandate__c.month()+'月共同拜访计划') ,
                        year__c=string.valueof(cp.callplan.callplandate__c.year()),
                        month__c=string.valueof(cp.callplan.callplandate__c.month())
                    );
                    insert newMJC;
                    mjcid=newMJC.id;
                    mjcmap.put(''+cp.callplan.CallPlanDate__c.year()+cp.CallPlan.CallPlanDate__c.month(),newmjc.id);
                }
                JointCall__c newJointCall=new JointCall__c(
                    CallPlan__c=cp.callplan.id,
                    name=cp.callplan.name,
                    CallPlanOwner18Digit__c=cp.callplan.Monthly_Call_Plan__r.OwnerId,
                    HCPID18digit__c=cp.callplan.HCP__r.Id,
                    MonthlyJointCall__c=mjcid,
                    isinplan__c=true,
                    Owner__c=userinfo.getuserid(),
                    UniqueId__c=string.valueof(cp.callplan.id).substring(0,15)+userinfo.getuserid().substring(0,15)
                );
                UpsertJointCallList.add(newJointCall);
                
                if(!MSRIds.containsKey(cp.callplan.Monthly_Call_Plan__r.OwnerId))
                {
                    Message__c message=new Message__c(name='协访通知',
                                                                              Content__c='您好，您的经理已将您定于'+cp.callplan.CallPlanDate__c.year()+'年'+cp.callplan.CallPlanDate__c.month()+'月'+cp.callplan.CallPlanDate__c.day()+'日的拜访计划：'+cp.callplan.name+' 设定为协访计划。',
                                                                              StartDate__c=date.today(),
                                                                              EndDate__c=cp.callplan.CallPlanDate__c,
                                                                              Type__c='医务信息'
                                                                              );
                     insert message;
                     MessageRecipient__c MR=new MessageRecipient__c(Message__c=message.id,Recipient__c=cp.callplan.Monthly_Call_Plan__r.OwnerId);
                     insertMessageRecipientList.add(MR);
                     
                     MSRIds.put(cp.callplan.Monthly_Call_Plan__r.OwnerId,cp.callplan.Monthly_Call_Plan__r.OwnerId);
                 }
            }
        }
        insert insertMessageRecipientList;
        upsert UpsertJointCallList UniqueId__c;
        pageReference pr = new pageReference('/'+MJCID);
        pr.setredirect(true);      
        return pr;
    }
    
    
    
    public void search(){
        callplan.clear();
        showerror=false;
        msg = null;
        
        
        if(JointCall.SearchDate__c==null){
            NullCallDateError='请填写拜访日期。';
            showError=true;
        }
        
        if(JointCall.SearchDate__c<=date.today()){
            NullCallDateError='请选择明天及以后的拜访日期。';
            showError=true;
        }        
        if(JointCall.SearchDate__c!=null){
            if(JointCall.SearchDate__c.tostartofmonth()!=planmonth){
                NullCallDateError='您正在做的是'+planmonth.month()+'月份的计划，请选择正确的日期。';
                showError=true;
            }
        }
        list<callplan__c> cpl=new list<callplan__c>();
        if(JointCall.SearchDate__c<>null && !showerror){

            if((MSRL != '0')&&(MSRL != null))
            {
               if((CityValue!= '0')&&(CityValue!= null))
               {
                cpl=[select id, ownerid__c,CreatedBy.Alias,name,CallPlanDate__c,Hospitalclass__c,HCPDepartment__c,HCP__c,CallPurpose__c,Monthly_Call_Plan__r.OwnerId,HCP__r.Id from callplan__c where Monthly_Call_Plan__r.OwnerId =: MSRL and 
                     salecity__c =:  CityValue and  CallPlanDate__c=:JointCall.SearchDate__c and CallWorkingtype__c='拜访' ];              
                   
               }
               else
               {
                cpl=[select id, ownerid__c,CreatedBy.Alias,name,CallPlanDate__c,Hospitalclass__c,HCPDepartment__c,HCP__c,CallPurpose__c,Monthly_Call_Plan__r.OwnerId,HCP__r.Id from callplan__c where Monthly_Call_Plan__r.OwnerId =: MSRL and 
                      CallPlanDate__c=:JointCall.SearchDate__c and CallWorkingtype__c='拜访' ];                         
               
               }

            }
            else
            {
                 if((CityValue!= '0')&&(CityValue!= null))
                 {
                    cpl=[select id, ownerid__c,CreatedBy.Alias,name,CallPlanDate__c,Hospitalclass__c,HCPDepartment__c,HCP__c,CallPurpose__c,Monthly_Call_Plan__r.OwnerId,HCP__r.Id from callplan__c where  salecity__c =:  CityValue and CallPlanDate__c=:JointCall.SearchDate__c and CallWorkingtype__c='拜访'  ];            
                                         
                 }
                 else
                 {
                    cpl=[select id, ownerid__c,CreatedBy.Alias,name,CallPlanDate__c,Hospitalclass__c,HCPDepartment__c,HCP__c,CallPurpose__c,Monthly_Call_Plan__r.OwnerId,HCP__r.Id from callplan__c where  CallPlanDate__c=:JointCall.SearchDate__c and CallWorkingtype__c='拜访' ];            
                                         
                 }   

            }

        }
        list<JointCall__c> MyJointCallList = [Select id, CallPlan__c From JointCall__c Where CallDate__c=:JointCall.SearchDate__c and Owner__c =: userinfo.getuserid()];
        Boolean haveCall = false;
        for(callPlan__c cp:cpl){
            haveCall = false;
            for(JointCall__c j : MyJointCallList )
            {
                if(cp.id == j.CallPlan__c)
                    haveCall = true; 
            }
            if(!haveCall)
                CallPlan.add(new callplanentry(cp));
        }
        if(cpl.size()<= 0)
        {
            msg = '此代表未做'+ JointCall.SearchDate__c.year() + '年' + JointCall.SearchDate__c.month() + '月'+ JointCall.SearchDate__c.day() + '日'+'拜访计划';
        }
        
    }
    
    //====递归找出下级的所有MSR ====
    public void SearchMsr(set<id> US){
        set<id> tempS=new set<id>();
        temps.clear();
        for(user u:AllUserList){
            if(us.contains(u.managerID)){
                if(u.Title__c == 'Sales Rep' && u.FunctionDepartment__c=='Medical Sales'){
                    AllMsr.add(u);
                    MSRList.add(new SelectOption(u.Id,u.Name));
                }else{
                    temps.add(u.id);
                }
            }
        }
        if(temps.size()>0){
            SearchMsr(temps);
        }
    }
    
    //====筛选要显示的MSR
    public void MSRFilter(){
        MSRList.clear();
        MSRList.add(new SelectOption('0','所有MSR'));
        for(user u:AllMsr){
            if( u.UserCity__c.contains(CityValue) || cityvalue=='0' ){
                MSRList.add(new SelectOption(u.Id,u.Name));
            }
        }
    }
    //筛选城市
    public List<SelectOption> CityList
    {
        get
        {
            if(CityList==null)
                CityList=new List<SelectOption>();
            
            CityList.clear();
            CityList.add(new SelectOption('0','所有城市'));
            if(CurrentUser.UserCity__c==NULL)
            {
                if(CurrentUser.UserAreaValue__c!=null){
                
                    for(Place__c p:PlaceL)
                    {
                        if(p.PlaceType__c=='City' && String.valueOf(CurrentUser.UserAreaValue__c).contains(p.Area__r.Name)){
                            CityList.add(new SelectOption(P.Name,P.Name));
                        }
                    }   
                }else{
                    if(CurrentUser.UserSubRegion__c!=null){
                        for(Place__c p:PlaceL)
                        {
                            if(p.PlaceType__c=='City' && CurrentUser.UserSubRegion__c==p.Subregion__r.Name){
                                CityList.add(new SelectOption(P.Name,P.Name));
                            }
                        }   
                    }else{
                        if(CurrentUser.UserRegion__c!=null){
                            for(Place__c p:PlaceL)
                            {
                                if(p.PlaceType__c=='City' && CurrentUser.UserRegion__c==p.Region__r.Name){
                                    CityList.add(new SelectOption(P.Name,P.Name));
                                }
                            }
                        }
                    }
                }
                    
            }
            else
            {
                List<String> arr=String.valueOf(CurrentUser.UserCity__c).split(';');
                if(arr!=NULL || arr.size()>0)
                {
                    for(String s:arr)
                        CityList.add(new SelectOption(s,s));
                }
            }
            return CityList;
        }
       set;
    }
    
    
    
    
    static testMethod  void test()
    {
        //run as RGM;
        Profile p = [select id from profile where Name='Regional General Manager' limit 1];
        User u = new User(alias = 'standtss', email='sdardr@testorgss.com',
        emailencodingkey='UTF-8', lastname='Testing', languagelocalekey='en_US',Title__c='MSR',
        localesidkey='en_US', profileid = p.Id,UserCity__c='广州',IsActive=true,
        UserAreaValue__c='广州区域',UserSubRegion__c='华南一区',UserRegion__c='华南区',
        timezonesidkey='America/Los_Angeles', username='stsers@testorg.com');
        insert u;
        
        Profile psup = [select id from profile where Name='Sales Supervisor - Trade' limit 1];
        User usup = new User(alias = 'standtss', email='sdardr@testorgss.com',
        emailencodingkey='UTF-8', lastname='Testing', languagelocalekey='en_US',Title__c='MSR',
        localesidkey='en_US', profileid = psup.Id,UserCity__c='广州',IsActive=true,managerid=u.id,
        UserAreaValue__c='广州区域',UserSubRegion__c='华南一区',UserRegion__c='华南区',
        timezonesidkey='America/Los_Angeles', username='sup@testorg.com');
        insert usup;
        
        Profile ptsr = [select id from profile where Name='Sales Rep - Trade' limit 1];
        User utsr = new User(alias = 'standtss', email='sdardr@testorgss.com',
        emailencodingkey='UTF-8', lastname='Testing', languagelocalekey='en_US',Title__c='MSR',
        localesidkey='en_US', profileid = ptsr.Id,UserCity__c='广州',IsActive=true,managerid=usup.id,
        UserAreaValue__c='广州区域',UserSubRegion__c='华南一区',UserRegion__c='华南区',
        timezonesidkey='America/Los_Angeles', username='tsr@testorg.com');
        insert utsr;
        
        system.runas(u){
            ApexPages.StandardController controller= new ApexPages.StandardController(new jointCall__c());
            CreateJointCall jointcall=new CreateJointCall(controller);
             
            
            
            jointcall.search();
            jointcall.MSRFilter();
            for(CallPlanEntry cp:jointcall.CallPlan){
                cp.checked=true;
            }
            jointcall.submit();
        }
        
        //run as admin;
        Profile p1 = [select id from profile where name='System Administrator' or name = '系统管理员' limit 1];
        User u2 = new User(alias = 'admin', email='admin@testorgss.com',
        emailencodingkey='UTF-8', lastname='ad', languagelocalekey='en_US',Title__c='TSR',
        localesidkey='en_US', profileid = p1.Id,UserCity__c='广州',IsActive=true,
        UserAreaValue__c='广州区域',UserSubRegion__c='华南一区',UserRegion__c='华南区',
        timezonesidkey='America/Los_Angeles', username='admin@testorg.com');
        insert u2;  
        
        system.runas(u2){
            ApexPages.StandardController controller= new ApexPages.StandardController(new jointCall__c());
            CreateJointCall jointcall=new CreateJointCall(controller);
            
            
            
            jointcall.search();
            jointcall.MSRFilter();
            for(CallPlanEntry cp:jointcall.CallPlan){
                cp.checked=true;
            }
            jointcall.submit();
        }
        
    }

    
}